#include <iostream>

using std::cout;
using std::endl;

class Base1
{
public:
    virtual 
    void a()
    {
        cout << "virtual void Base1::a()" << endl;
    }

    virtual 
    void b()
    {
        cout << "virtual void Base1::b()" << endl;
    }

    virtual 
    void c()
    {
        cout << "virtual void Base1::c()" << endl;
    }
};

class Base2
{
public:
    virtual 
    void a()
    {
        cout << "virtual void Base2::a()" << endl;
    }

    virtual 
    void b()
    {
        cout << "virtual void Base2::b()" << endl;
    }

    void c()
    {
        cout << "void Base2::c()" << endl;
    }

    void d()
    {
        cout << "void Base2::d()" << endl;
    }
};

class Derived
: public Base1
, public Base2
{
public:
    virtual
    void a()
    {
        cout << "virtual void Derived::a()" << endl;
    }

    void c()//虚函数
    {
        cout << "void Derived::c()" << endl;
    }

    void d()
    {
        cout << "void Derived::d()" << endl;
    }
};

class Derived2
: public Derived
{
public:
    void c()//不知道该函数是虚函数还是非虚函数?
    {
        cout << "void Derived2::c()" << endl;
    }

};

void test()
{
    cout << "sizeof(Base1) = " << sizeof(Base1) << endl;
    cout << "sizeof(Base2) = " << sizeof(Base2) << endl;
    cout << "sizeof(Derived) = " << sizeof(Derived) << endl;

    cout <<endl;
    Derived derived;
    printf("&derived = %p\n", &derived);

    cout << endl;
    Base1 *pbase1 = &derived;
    printf("pbase1 = %p\n", pbase1);
    pbase1->a();//Derived::a()
    pbase1->b();//Base1::a()
    pbase1->c();//Derived::c()

    cout << endl;
    Base2 *pbase2 = &derived;
    printf("pbase2 = %p\n", pbase2);
    pbase2->a();//Derived::a()
    pbase2->b();//Base2::b()
    pbase2->c();//Base2::c()
    pbase2->d();//Base2::d()

    cout << endl;
    Derived *pderived = &derived;
    printf("pderived = %p\n", pderived);
    pderived->a();//Derived::a()
    /* pderived->b();//error, b函数具备二义性 */
    pderived->Base1::b();//Base1::b()
    pderived->Base2::b();//Base2::b()
    pderived->c();//Derived::c()
    pderived->d();//Derived::d()

    cout << endl;
    Derived2 d2;
    Derived *pd = &d2;
    pd->c();//Derived

}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

